package com.fly.demo.web.sse;

import java.time.Duration;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fly.demo.service.DataService;

import reactor.core.publisher.Flux;

/**
 * 解决推送数据一致问题
 */
@RestController
public class SSE1Controller
{
    @Autowired
    DataService dataService;
    
    String pushData;
    
    /**
     * webflux 实现的sse
     * 
     * @param userId
     * @return
     * @see [类、类#方法、类#成员]
     */
    @GetMapping(value = "/sse/v1", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> sse()
    {
        // 与SseEmitter相比，客户端推送时间一致性较差
        return Flux.interval(Duration.ofSeconds(10)).map(d -> ServerSentEvent.<String> builder().comment("pushData").data(pushData).build()).log();
    }
    
    /**
     * 刷新推送字符串数据
     * 
     * @return
     * @see [类、类#方法、类#成员]
     */
    @Scheduled(cron = "0/10 * 7-23 * * ?")
    private void publish()
    {
        pushData = ToStringBuilder.reflectionToString(dataService.getArticle(), ToStringStyle.SIMPLE_STYLE);
    }
    
    /**
     * 获取推送字符串数据，注意此方法每个客户端执行获取到的数据是不一致的
     * 
     * @return
     * @see [类、类#方法、类#成员]
     */
    @Deprecated
    String getData()
    {
        return ToStringBuilder.reflectionToString(dataService.getArticle(), ToStringStyle.SIMPLE_STYLE);
    }
}
